/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.jSky.generator.builder.ruleBuilder;

import java.util.ArrayList;
import java.util.Collection;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import ru.jSky.factory.EdidGenerationStrategyFactory;
import ru.jSky.factory.SimpleMajorModificationCommandFactory;
import ru.jSky.generator.command.ComposeGenerationCommand;
import ru.jSky.generator.command.CreationCommand;
import ru.jSky.generator.command.CreationWithTemplateCommand;
import ru.jSky.generator.command.EdidGenerationByBaseStrategy;
import ru.jSky.generator.command.GenerationCommand;
import ru.jSky.generator.command.ModificationCommand;
import ru.jSky.generator.command.rule.Rule;
import ru.jSky.generator.command.rule.SimpleRule;
import ru.jSky.interfaces.Enchantment;
import ru.jSky.interfaces.JSkyMod;
import ru.jSky.interfaces.Major;
import ru.jSky.matcher.AlwaysTrueMatcher;

/**
 *
 * @author Rakev
 */
public class EnchantmentionGeneratorRuleBuilder<T extends Major> {

    private JSkyMod editingMod;
    private Enchantment imposedEnchantment;
    private Matcher<T> ruleMatcher;
    private String nameAppendix;
    private boolean templated;

    public EnchantmentionGeneratorRuleBuilder(JSkyMod editingMod, Enchantment imposedEnchantment) {
        this.editingMod = editingMod;
        this.imposedEnchantment = imposedEnchantment;
        this.ruleMatcher = new AlwaysTrueMatcher<>();
        this.nameAppendix = "";
    }

    public EnchantmentionGeneratorRuleBuilder addRuleMatcher(Matcher<T> ruleMatcher) {
        this.ruleMatcher = Matchers.allOf(this.ruleMatcher, ruleMatcher);
        return this;
    }

    public EnchantmentionGeneratorRuleBuilder addNameAppendix(String appendix) {
        this.nameAppendix += " " + appendix;
        return this;
    }

    public EnchantmentionGeneratorRuleBuilder setTemplated() {
        this.templated = true;
        return this;
    }

    public EnchantmentionGeneratorRuleBuilder unsetTemplated() {
        this.templated = false;
        return this;
    }

    public Rule<T> build() {
        CreationCommand<T> creationCommand = createCreationCommand();
        Collection<ModificationCommand<T>> modificationCommands = createModificationCommands();

        GenerationCommand<T> enchantmentGenerationCommand = new ComposeGenerationCommand<>(creationCommand, modificationCommands);

        return new SimpleRule<>(ruleMatcher, enchantmentGenerationCommand);
    }

    private CreationCommand<T> createCreationCommand() {
        EdidGenerationByBaseStrategy<T> edidGenerationStrategy = new EdidGenerationStrategyFactory().create(imposedEnchantment);
        if (templated) {
            return new CreationWithTemplateCommand(editingMod, edidGenerationStrategy);
        } else {
            return new CreationCommand(editingMod, edidGenerationStrategy);
        }
    }

    private Collection<ModificationCommand<T>> createModificationCommands() {
        SimpleMajorModificationCommandFactory modificationCommandFactory = new SimpleMajorModificationCommandFactory();
        Collection<ModificationCommand<T>> modificationCommands = new ArrayList<>();
        ModificationCommand<T> enchantmentAdder = modificationCommandFactory.createEnchantmeningtModificationCommand(imposedEnchantment);
        modificationCommands.add(enchantmentAdder);
        if (!nameAppendix.isEmpty()) {
            ModificationCommand<T> appendexAdder = modificationCommandFactory.createConcatNamingModificationCommand(nameAppendix);
            modificationCommands.add(appendexAdder);
        }

        return modificationCommands;
    }
}
